namespace Gadgeteer.Modules.Mekalogic
{
	/// <summary>
	/// Provides methods for interacting with a remote TCP server
	/// </summary>
	public interface ITcpServerConnection
	{
		/// <summary>
		/// Indicates the <see cref="ITcpServerConnection"/> is ready to connnect
		/// </summary>
		bool IsReady { get; }

		/// <summary>
		/// Indicates the <see cref="ITcpServerConnection"/> is connected and can send data
		/// </summary>
		bool CanSendData { get; }

		/// <summary>
		/// Connect to a remote TCP server
		/// </summary>
		/// <param name="serverAddress">The IP address or DNS name of the TCP Server. NOTE: Underlying transport must be able to resolve DNS to use a DNS name</param>
		/// <param name="port">The TCP port to connect to</param>
		/// <returns>
		/// <value>true</value> if connection successful
		/// <value>false</value> if connection failed
		/// </returns>
		bool Connect(string serverAddress, int port);

		/// <summary>
		/// Disconnect from the remote TCP server
		/// </summary>
		/// <returns>
		/// <value>true</value> if disconnection successful
		/// <value>false</value> if disconnection failed
		/// </returns>
		bool Disconnect();

		/// <summary>
		/// Sends data to the TCP server.  Blocks until finished.  NOTE: Some transports may have long delays, recommended to call from separate thread.
		/// </summary>
		/// <param name="data">The data for transmission.  For http data must include the CRLF and all headers as required.</param>
		/// <returns>
		/// <value>true</value> if transmission successful
		/// <value>false</value> if transmission failed
		/// </returns>
		bool SendData(string data);

		/// <summary>
		/// Receive data from the TCP Server
		/// </summary>
		/// <param name="timeout">The timout to wait for data in milliseconds.  Blocks for the <param name="timeout">timeout</param> duration</param>
		/// <param name="data">The data received (if any) as a string</param>
		/// <param name="returnOnFirstDataReceived">
		/// <value>true</value> will wait until any data is received, or the timeout.
		/// <value>false</value> will wait for the timeout</param>
		/// <returns>
		/// <value>true</value> if data was received
		/// <value>false</value> if no data was received
		/// </returns>
		bool ReceiveData(int timeout, out string data, bool returnOnFirstDataReceived);

		/// <summary>
		/// Indicates that at least one packet has been received after a call to <see cref="ReceiveData"/>
		/// </summary>
		bool IsDataReceived { get; }
	}
}
